<template>
  <div>
    <h3>
      贷款计算器
      <van-tag round type="warning" plain size="medium">{{ calcName }}</van-tag>
    </h3>

    <h4>
      <van-tag mark type="primary" size="large">{{ bankName }}</van-tag>
    </h4>
    <van-tag color="#ffe1e1" text-color="#ad0000">政策导读</van-tag>

    <van-tag color="#ffffff" text-color="#7f7f7f">{{
      this.getPolicies
    }}</van-tag>

    <van-form @submit="onSubmit" scroll-to-error ref="form">
      <van-field
        name="loanPrice"
        v-model="price"
        label="贷款金额"
        placeholder="单位:万元"
      >
        <template #extra>
          万元
        </template>
      </van-field>
      <van-field
        name="loanTerm"
        v-model="term"
        label="期限"
        placeholder="单位:月"
        disabled
      >
        <template #extra>
          月
        </template>
      </van-field>
      <van-field
        name="loanRate"
        v-model="rate"
        label="贷款年利率"
        placeholder="请输入百分数,如: 4.65"
        disabled
      >
        <template #extra>
          %
        </template>
      </van-field>
      <van-field name="loanType" label="贷款方式" disabled>
        <template #input>
          <van-radio-group v-model="loanType" direction="horizontal" disabled>
            <van-radio name="1">等额本金</van-radio>
            <van-radio name="2">等额本息</van-radio>
            <van-radio name="3">先息后本</van-radio>
            <van-radio name="4">气球贷</van-radio>
          </van-radio-group>
        </template>
      </van-field>

      <div v-if="loanType == 4">
        <van-divider
          :style="{
            color: '#1989fa',
            borderColor: '#1989fa',
            padding: '0 16px'
          }"
          >气球贷</van-divider
        >
        <van-field name="ballonType" label="气球贷-还款方式">
          <template #input>
            <van-radio-group
              v-model="ballonType"
              direction="horizontal"
              disabled
            >
              <van-radio name="1">等额本金</van-radio>
              <van-radio name="2">等额本息</van-radio>
              <van-radio name="3">先息后本</van-radio>
            </van-radio-group>
          </template>
        </van-field>
        <div v-if="ballonType == 3">
          <van-field
            name="ballonPrincipalRate"
            v-model="ballonPrincipalRate"
            label="气球贷-每期本金还款比例"
            disabled
          >
            <template #extra>
              %
            </template>
          </van-field>
          <van-field
            name="ballonPrincipalRepayPeriod"
            v-model="ballonPrincipalRepayPeriod"
            label="气球贷-本金还款周期"
            disabled
          >
            <template #extra>
              月
            </template>
          </van-field>
        </div>
        <div v-if="ballonType < 3">
          <van-field name="ballonRepayPeriod" label="气球贷-还款周期">
            <template #input>
              <van-radio-group
                v-model="ballonRepayPeriod"
                direction="horizontal"
                disabled
              >
                <van-radio name="1">按月还款</van-radio>
                <van-radio name="3">按季还款</van-radio>
                <van-radio name="6">半年还款</van-radio>
                <van-radio name="12">按年还款</van-radio>
              </van-radio-group>
            </template>
          </van-field>
        </div>
        <van-field name="ballonFloat" label="气球贷-利率浮动形式">
          <template #input>
            <van-radio-group
              v-model="ballonFloat"
              direction="horizontal"
              disabled
            >
              <van-radio name="0">无</van-radio>
              <van-radio name="1">上浮</van-radio>
              <van-radio name="2">下浮</van-radio>
            </van-radio-group>
          </template>
        </van-field>
        <div v-if="ballonFloat > 0">
          <van-field
            name="ballonFloatRate"
            v-model="ballonFloatRate"
            label="气球贷-浮动比例"
            placeholder="请输入百分数,如: 20"
            readonly
          >
            <template #extra>
              %
            </template>
          </van-field>
        </div>
        <van-field
          name="ballonLimitTerm"
          v-model="ballonLimitTerm"
          label="气球贷-还款期限"
          placeholder="单位:月"
          disabled
        >
          <template #extra>
            月
          </template>
        </van-field>
      </div>

      <van-button round type="primary" native-type="submit" class="submit-btn">
        开始计算
      </van-button>
      <CalculatorTable
        v-if="this.step === 5"
        :tableData="tableData"
        :totalData="totalData"
      ></CalculatorTable>
    </van-form>
  </div>
</template>

<script>
import CalculatorTable from "./CalculatorTable";

export default {
  name: "CalculatorForm",
  components: {
    CalculatorTable
  },
  props: {
    calcInfo: Object
  },
  inject: ["changeStep"],
  data() {
    return {
      step: 4,
      bankName: this.calcInfo.bankInfo.data.bankName,
      loanType: this.calcInfo.selected.options.calcType + "",
      price: this.calcInfo.loanPrice,
      term: this.calcInfo.selected.options.loanTerm,
      rate: this.calcInfo.selected.options.rate,
      calcName: this.calcInfo.selected.options.calcName,
      ballonType: this.calcInfo.selected.options.ballonType + "",
      ballonRepayPeriod: this.calcInfo.selected.options.ballonRepayPeriod + "",
      ballonLimitTerm: this.calcInfo.selected.options.ballonLimitTerm,
      ballonFloat: this.calcInfo.selected.options.ballonFloat + "",
      ballonFloatRate: this.calcInfo.selected.options.ballonFloatRate,
      ballonPrincipalRate:
        this.calcInfo.selected.options.ballonPrincipalRate + "",
      ballonPrincipalRepayPeriod:
        this.calcInfo.selected.options.ballonPrincipalRepayPeriod + "",
      totalData: {},
      tableData: []
    };
  },
  computed: {
    getPolicies() {
      let policies = this.calcInfo.bankInfo.data.policies;
      if (policies.length < 2 && policies.indexOf("0") != -1) {
        return "暂无";
      } else {
        return policies.join();
      }
    }
  },
  methods: {
    onSubmit(values) {
      let formData = values;
      this.calculator(formData);
      this.step = 5;
    },
    calculator(formData) {
      let loanType = formData.loanType;
      if (loanType == 1) {
        // 等额本金
        this.equalPrincipal(formData);
      } else if (loanType == 2) {
        // 等额本息
        this.equalPrincipalAndInterest(formData);
      } else if (loanType == 3) {
        // 先息后本
        this.firstInterestLastPrincipal(formData);
      } else if (loanType == 4) {
        // 气球贷
        this.ballonLoan(formData);
      } else {
        console.log("参数错误");
      }

      this.getTotalData(loanType);
    },
    equalPrincipalAndInterest(formData) {
      // 计算等额本息
      let loanPrice = formData.loanPrice * 10000;
      let loanTerms = formData.loanTerm;
      let loanRate = formData.loanRate / 100;
      let calcTableData = new Array();
      let monLoanRate = loanRate / 12; // 月利率
      let firstMonInterest = loanPrice * monLoanRate; // 第一个月的利息 = 贷款总额 * 月利率
      let sumPrincipal = 0; // 已缴纳的本金
      for (let i = 0; i < loanTerms; i++) {
        // i 是贷款当前月，从 0 ～ (length - 1)
        let monPayment =
          (loanPrice * monLoanRate * Math.pow(1 + monLoanRate, loanTerms)) /
          (Math.pow(1 + monLoanRate, loanTerms) - 1); // 借款本金×月利率×（1＋月利率）^还款月数/[（1＋月利率）^还款月数－1]
        let monInterest;
        if (i == 0) {
          monInterest = firstMonInterest; // 第一个月的利息
        } else {
          monInterest = (loanPrice - sumPrincipal) * monLoanRate; // 每个月的利息 = 剩余本金 * 月利率
        }
        let monPrincipal = monPayment - monInterest; // 每个月的本金 = 月供 - 月利息
        sumPrincipal += monPrincipal; // 计算已缴纳的本金
        let balance = loanPrice - sumPrincipal;
        if (loanTerms == i + 1) {
          balance = 0.0; // 最后一个月，余额要置0
        }
        let rowData = {
          term: i + 1,
          monPayment: this.myRound(monPayment), // 月供
          monPrincipal: this.myRound(monPrincipal), // 月供本金
          monInterest: this.myRound(monInterest), // 月供利息
          balance: this.myRound(balance) // 剩余本金
        };
        calcTableData.push(rowData);
      }
      this.tableData = calcTableData;
    },
    equalPrincipal(formData) {
      // 计算等额本金
      let loanPrice = formData.loanPrice * 10000;
      let loanTerms = formData.loanTerm;
      let loanRate = formData.loanRate / 100;
      let calcTableData = new Array();
      for (let i = 0; i < loanTerms; i++) {
        // i 是贷款当前月，从 0 ～ (length - 1)
        let monPrincipal = loanPrice / loanTerms; // 每月还款本金=贷款总额/贷款月数 ；
        let balance = loanPrice - (i + 1) * monPrincipal; // 贷款本金余额=贷款总额-已还款月数*每月还款本金
        if (loanTerms == i + 1) {
          balance = 0.0; // 最后一个月，余额要置0
        }
        let monInterest = (loanPrice - i * monPrincipal) * (loanRate / 12); // 每月还款利息=贷款本金余额*贷款月利率（贷款月利率=年利率/12）
        let monPayment = monPrincipal + monInterest; // 每月还款额=每月还款本金+每月还款利息；

        let rowData = {
          term: i + 1,
          monPayment: this.myRound(monPayment),
          monPrincipal: this.myRound(monPrincipal),
          monInterest: this.myRound(monInterest),
          balance: this.myRound(balance)
        };
        calcTableData.push(rowData);
      }
      this.tableData = calcTableData;
    },
    firstInterestLastPrincipal(formData) {
      // 计算先息后本
      let loanPrice = formData.loanPrice * 10000;
      let loanTerms = formData.loanTerm;
      let loanRate = formData.loanRate / 100;
      let loanInterest = loanPrice * loanRate;
      let calcTableData = new Array();
      for (let i = 0; i < loanTerms; i++) {
        // i 是贷款当前月，从 0 ～ (length - 1)
        let monPrincipal = 0;
        if (i == loanTerms - 1) {
          // 最后一个月，偿还所有本金
          monPrincipal = loanPrice;
        }
        let balance = loanPrice - monPrincipal; // 剩余待还款本金
        if (loanTerms == i + 1) {
          balance = 0.0; // 最后一个月，余额要置0
        }
        let monInterest = loanInterest / loanTerms; // 每月还款利息 = 总利息 / 还款期数
        let monPayment = monPrincipal + monInterest; // 每月还款额=每月还款本金+每月还款利息；

        let rowData = {
          term: i + 1,
          monPayment: this.myRound(monPayment),
          monPrincipal: this.myRound(monPrincipal),
          monInterest: this.myRound(monInterest),
          balance: this.myRound(balance)
        };
        calcTableData.push(rowData);
      }
      this.tableData = calcTableData;
    },

    ballonLoan(formData) {
      // 气球贷计算
      let loanPrice = formData.loanPrice * 10000; // 贷款金额
      let loanTerms = formData.loanTerm; // 贷款月数
      let loanRate = formData.loanRate / 100; // 贷款利率
      let ballonType = formData.ballonType; // 气球贷类型
      let ballonRepayPeriod = formData.ballonRepayPeriod; // 气球贷还款周期
      let ballonLimitTerm = formData.ballonLimitTerm; // 气球贷还款期限
      let ballonFloat = formData.ballonFloat; // 气球贷是否浮动
      let ballonFloatRate = formData.ballonFloatRate; // 气球贷浮动比例
      let ballonLoanPeriodTerms = loanTerms / ballonRepayPeriod; // 气球贷真实的还款期数
      // --------- 先息后本 ----------
      let ballonPrincipalRate = formData.ballonPrincipalRate / 100; // 气球贷本金还款比例（仅适用于先息后本）
      let ballonPrincipalRepayPeriod = formData.ballonPrincipalRepayPeriod; // 气球贷本金还款比例（仅适用于先息后本）
      if (ballonFloat == 0) {
        ballonFloatRate = 0; // 如果气球贷没有利率浮动，则利率浮动比例置为0
      }
      let ballonLoanRate =
        Math.round(loanRate * (1 + ballonFloatRate / 100) * 10000) / 10000; // 上浮之后的年利率
      if (ballonFloat == 2) {
        ballonLoanRate =
          Math.round(loanRate * (1 - ballonFloatRate / 100) * 10000) / 10000; // 下浮之后的年利率
      }
      let ballonPeriodLoanRate = (ballonLoanRate * ballonRepayPeriod) / 12; // 还款周期利率
      let balance = loanPrice; // 上期还款后剩余本金
      let currentPayment = 0; // 本期还款额
      let currentInterest = 0; // 本期应还利息
      let currentPrincipal = 0; // 本期还款本金
      let calcTableData = new Array();
      if (ballonType == 1) {
        // 气球贷类型是等额本金
        console.log("等额本金");
        for (let i = 1; i < ballonLoanPeriodTerms; i++) {
          // 第 1 -> （T-1） 期 （ T = ballonLoanPeriodTerms）
          currentInterest = balance * ballonPeriodLoanRate; // 本期应还利息
          currentPrincipal =
            (((loanPrice * 1.0) / ballonLimitTerm) * 100) / 100; // 本期应还本金
          currentPayment = currentPrincipal + currentInterest; // 本期还款额,四舍五入,小数点保留2位
          balance = balance - currentPrincipal; // 剩余还款本金
          let rowData = {
            term: i,
            monPayment: this.myRound(currentPayment),
            monPrincipal: this.myRound(currentPrincipal),
            monInterest: this.myRound(currentInterest),
            balance: this.myRound(balance)
          };
          calcTableData.push(rowData);
        }
        // 第 T 期
        currentInterest = balance * ballonPeriodLoanRate; // 本期应还利息, 小数点保留2位
        currentPrincipal = balance; // 本期还款本金,四舍五入,小数点保留2位
        currentPayment = currentInterest + currentPrincipal;
        balance = 0.0;
        let rowData = {
          term: ballonLoanPeriodTerms,
          monPayment: this.myRound(currentPayment),
          monPrincipal: this.myRound(currentPrincipal),
          monInterest: this.myRound(currentInterest),
          balance: this.myRound(balance)
        };
        calcTableData.push(rowData);
      } else if (ballonType == 2) {
        // 气球贷类型是等额本息
        console.log("等额本息");
        for (let i = 1; i < ballonLoanPeriodTerms; i++) {
          // 第1---(T-1)期
          currentInterest = balance * ballonPeriodLoanRate;
          currentPayment =
            (loanPrice * ballonPeriodLoanRate) /
            (1 - Math.pow(1 + ballonPeriodLoanRate, -ballonLimitTerm));
          currentPrincipal = currentPayment - currentInterest;
          balance = balance - currentPrincipal;
          let rowData = {
            term: i,
            monPayment: this.myRound(currentPayment),
            monPrincipal: this.myRound(currentPrincipal),
            monInterest: this.myRound(currentInterest),
            balance: this.myRound(balance)
          };
          calcTableData.push(rowData);
        }
        // 第 T 期
        currentInterest = balance * ballonPeriodLoanRate;
        currentPrincipal = balance;
        currentPayment = currentInterest + currentPrincipal;
        balance = 0.0;
        let rowData = {
          term: ballonLoanPeriodTerms,
          monPayment: this.myRound(currentPayment),
          monPrincipal: this.myRound(currentPrincipal),
          monInterest: this.myRound(currentInterest),
          balance: this.myRound(balance)
        };
        calcTableData.push(rowData);
      } else if (ballonType == 3) {
        // 气球贷类型是先息后本
        console.log("先息后本");
        for (let i = 1; i < loanTerms; i++) {
          // 第 1 -> （T-1） 期 （ T = ballonLoanPeriodTerms）
          currentInterest = balance * (ballonLoanRate / 12); // 本期应还利息
          currentPrincipal = 0;
          if (i % ballonPrincipalRepayPeriod == 0) {
            currentPrincipal = loanPrice * ballonPrincipalRate;
          }
          currentPayment = currentPrincipal + currentInterest; // 本期还款额,四舍五入,小数点保留2位
          balance = balance - currentPrincipal; // 剩余还款本金
          let rowData = {
            term: i,
            monPayment: this.myRound(currentPayment),
            monPrincipal: this.myRound(currentPrincipal),
            monInterest: this.myRound(currentInterest),
            balance: this.myRound(balance)
          };
          calcTableData.push(rowData);
        }

        // 第 T 期
        currentInterest = balance * (ballonLoanRate / 12);
        currentPrincipal = balance;
        currentPayment = currentInterest + currentPrincipal;
        balance = 0.0;
        let rowData = {
          term: loanTerms,
          monPayment: this.myRound(currentPayment),
          monPrincipal: this.myRound(currentPrincipal),
          monInterest: this.myRound(currentInterest),
          balance: this.myRound(balance)
        };
        calcTableData.push(rowData);
      } else {
        console.log("ballonType 参数错误");
      }

      this.tableData = calcTableData;
    },

    getTotalData(loanType) {
      // 获取合计数据（月供总和、利息总和）
      let tableData = this.tableData;
      let sumPayment = tableData.reduce(function(total, currentValue) {
        return total + currentValue.monPayment;
      }, 0);
      let sumInterest = tableData.reduce(function(total, currentValue) {
        return total + currentValue.monInterest;
      }, 0);

      this.totalData = {
        loanType: loanType,
        sumPayment: this.myRound(sumPayment),
        sumInterest: this.myRound(sumInterest)
      };
    },

    myRound(aNum) {
      return Math.round(aNum * 100) / 100;
    }
  }
};
</script>

<style>
.return-btn {
  position: absolute;
  top: 16px;
  right: 24px;
}
</style>
